package com.xiaoqinag.ds.tree;

import com.alibaba.fastjson.annotation.JSONField;

import java.util.Objects;

public class Node<T extends Comparable> implements Comparable<Node> {
    private NodeColor color;
    private T data;
    private Node left;
    private Node right;
    @JSONField(serialize = false)
    private Node parent;

    public Node() {
        color = NodeColor.Red;
    }

    public Node(T data) {
        this();
        this.data = data;
    }

    public Node(T data, Node left, Node right) {
        this(data);
        this.left = left;
        this.right = right;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public Node getLeft() {
        return left;
    }

    public void setLeft(Node left) {
        this.left = left;
        if (left != null) {
            left.parent = this;
        }
    }

    public Node getRight() {
        return right;
    }

    public void setRight(Node right) {
        this.right = right;
        if (right != null) {
            right.parent = this;
        }
    }

    public Node getParent() {
        return parent;
    }

    public void setParent(Node parent) {
        this.parent = parent;
    }

    public NodeColor getColor() {
        return color;
    }

    public void setColor(NodeColor color) {
        this.color = color;
    }

    public boolean isRed() {
        return color == NodeColor.Red;
    }

    public void changeColor() {
        color = color == NodeColor.Red ? NodeColor.Black : NodeColor.Red;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Node<?> node = (Node<?>) o;
        return Objects.equals(data, node.data) &&
                Objects.equals(left, node.left) &&
                Objects.equals(right, node.right);
    }

    @Override
    public int hashCode() {
        return Objects.hash(data, left, right);
    }

    @Override
    public int compareTo(Node o) {
        return this.data.compareTo(o.data);
    }

    public enum NodeColor {
        Red,
        Black,
    }
}
